//! # API网关增强功能综合测试
//!
//! 测试认证、限流、路由等核心功能的集成

use crate::auth::*;
use crate::rate_limit::*;
use crate::rate_limit::algorithms::*;
use crate::rate_limit::storage::*;
use crate::rate_limit::strategies::*;
use axum::http::HeaderMap;
use std::sync::Arc;
use std::time::Duration;

#[tokio::test]
async fn test_jwt_authentication_integration() {
    // 创建JWT认证提供者
    let jwt_config = JwtConfig::default();
    let provider = JwtAuthProvider::new(jwt_config).await.unwrap();

    // 生成测试令牌
    let claims = JwtClaims::new("test_user".to_string(), Duration::from_hours(1))
        .add_custom_claim("name".to_string(), serde_json::Value::String("Test User".to_string()));
    
    let token = provider.generate_token(&claims).await.unwrap();

    // 创建认证上下文
    let mut headers = HeaderMap::new();
    headers.insert("authorization", format!("Bearer {}", token).parse().unwrap());
    
    let context = AuthContext::new(
        headers,
        "GET".to_string(),
        "/api/users".to_string(),
        Some("127.0.0.1".to_string()),
    );

    // 执行认证
    let result = provider.authenticate(&context).await;
    assert!(result.is_ok());
    
    let principal = result.unwrap();
    assert_eq!(principal.id, "test_user");

    // 测试授权
    let resource = Resource::new("user-service".to_string(), "/api/users".to_string(), "GET".to_string());
    let authorized = provider.authorize(&principal, &resource).await.unwrap();
    // 默认情况下应该被拒绝（没有特定权限）
    assert!(!authorized);
}

#[tokio::test]
async fn test_api_key_authentication_integration() {
    // 创建API Key认证提供者
    let provider = ApiKeyAuthProvider::new();
    
    // 添加测试API Key
    let key = "sk_test_12345";
    let key_info = ApiKeyInfo::new("test_service".to_string(), vec!["read:users".to_string()]);
    provider.add_key(key.to_string(), key_info).await.unwrap();

    // 创建认证上下文
    let mut headers = HeaderMap::new();
    headers.insert("x-api-key", key.parse().unwrap());
    
    let context = AuthContext::new(
        headers,
        "GET".to_string(),
        "/api/users".to_string(),
        Some("127.0.0.1".to_string()),
    );

    // 执行认证
    let result = provider.authenticate(&context).await;
    assert!(result.is_ok());
    
    let principal = result.unwrap();
    assert!(principal.has_permission("read:users"));

    // 测试授权
    let resource = Resource::new("user-service".to_string(), "/api/users".to_string(), "GET".to_string());
    let authorized = provider.authorize(&principal, &resource).await.unwrap();
    assert!(authorized); // 应该被授权，因为有read权限
}

#[tokio::test]
async fn test_rate_limiting_integration() {
    // 创建存储和算法
    let storage = Arc::new(MemoryStorage::new());
    let algorithm = Box::new(TokenBucketAlgorithm::new(storage.clone()));
    
    // 创建限流器
    let mut limiter = RateLimiter::new(algorithm, storage.clone());
    
    // 添加IP限流策略
    let rate_config = RateLimitConfig {
        max_requests: 5,
        window_duration: Duration::from_secs(60),
        burst_capacity: Some(5),
        refill_rate: Some(1),
        enabled: true,
        ..Default::default()
    };
    
    let strategy = Box::new(IpBasedStrategy::new(rate_config));
    limiter = limiter.add_strategy(strategy);

    // 创建请求上下文
    let context = RequestContext::new("/api/test".to_string(), "GET".to_string())
        .with_client_ip("192.168.1.100".parse().unwrap());

    // 测试前5个请求应该成功
    for i in 0..5 {
        let decision = limiter.is_allowed(&context).await.unwrap();
        assert!(decision.allowed, "Request {} should be allowed", i + 1);
        assert_eq!(decision.remaining, 4 - i);
    }

    // 第6个请求应该被拒绝
    let decision = limiter.is_allowed(&context).await.unwrap();
    assert!(!decision.allowed, "Request 6 should be rate limited");
}

#[tokio::test]
async fn test_multiple_rate_limit_strategies() {
    // 创建存储和算法
    let storage = Arc::new(MemoryStorage::new());
    let algorithm = Box::new(FixedWindowAlgorithm::new(storage.clone()));
    
    // 创建限流器
    let mut limiter = RateLimiter::new(algorithm, storage.clone());
    
    // 添加IP限流策略
    let ip_config = RateLimitConfig {
        max_requests: 10,
        window_duration: Duration::from_secs(60),
        enabled: true,
        ..Default::default()
    };
    let ip_strategy = Box::new(IpBasedStrategy::new(ip_config));
    limiter = limiter.add_strategy(ip_strategy);
    
    // 添加用户限流策略
    let user_config = RateLimitConfig {
        max_requests: 3,
        window_duration: Duration::from_secs(60),
        enabled: true,
        ..Default::default()
    };
    let user_strategy = Box::new(UserBasedStrategy::new(user_config));
    limiter = limiter.add_strategy(user_strategy);

    // 创建请求上下文
    let context = RequestContext::new("/api/test".to_string(), "GET".to_string())
        .with_client_ip("192.168.1.100".parse().unwrap())
        .with_user_id("user123".to_string());

    // 测试用户限流（更严格）
    for i in 0..3 {
        let decision = limiter.is_allowed(&context).await.unwrap();
        assert!(decision.allowed, "User request {} should be allowed", i + 1);
    }

    // 第4个用户请求应该被拒绝（用户限流触发）
    let decision = limiter.is_allowed(&context).await.unwrap();
    assert!(!decision.allowed, "User request 4 should be rate limited");
}

#[tokio::test]
async fn test_auth_provider_factory() {
    use crate::auth::providers::*;
    use std::collections::HashMap;

    // 测试JWT提供者创建
    let mut jwt_config = HashMap::new();
    jwt_config.insert("secret".to_string(), "test-secret".to_string());
    
    let jwt_provider = AuthProviderFactory::create_provider(
        AuthProviderType::Jwt,
        jwt_config,
    ).await;
    
    assert!(jwt_provider.is_ok());
    assert_eq!(jwt_provider.unwrap().get_provider_name(), "jwt");

    // 测试API Key提供者创建
    let api_key_provider = AuthProviderFactory::create_provider(
        AuthProviderType::ApiKey,
        HashMap::new(),
    ).await;
    
    assert!(api_key_provider.is_ok());
    assert_eq!(api_key_provider.unwrap().get_provider_name(), "api_key");
}

#[tokio::test]
async fn test_auth_manager() {
    use crate::auth::providers::*;

    let mut manager = AuthManager::new();
    
    // 添加JWT提供者
    let jwt_config = JwtConfig::default();
    let jwt_provider = JwtAuthProvider::new(jwt_config).await.unwrap();
    manager.add_provider("jwt".to_string(), Box::new(jwt_provider));
    
    // 添加API Key提供者
    let api_key_provider = ApiKeyAuthProvider::new();
    manager.add_provider("api_key".to_string(), Box::new(api_key_provider));
    
    // 测试获取提供者
    let jwt_provider = manager.get_provider(Some("jwt"));
    assert!(jwt_provider.is_some());
    assert_eq!(jwt_provider.unwrap().get_provider_name(), "jwt");
    
    let api_key_provider = manager.get_provider(Some("api_key"));
    assert!(api_key_provider.is_some());
    assert_eq!(api_key_provider.unwrap().get_provider_name(), "api_key");
    
    // 测试默认提供者
    let default_provider = manager.get_provider(None);
    assert!(default_provider.is_some());
    assert_eq!(default_provider.unwrap().get_provider_name(), "jwt");
}

#[tokio::test]
async fn test_memory_storage_performance() {
    let storage = MemoryStorage::new();
    let key_prefix = "perf_test";
    let num_operations = 1000;

    // 性能测试：并发写入
    let start = std::time::Instant::now();
    let mut handles = vec![];
    
    for i in 0..num_operations {
        let storage_clone = &storage;
        let key = format!("{}_{}", key_prefix, i);
        let handle = tokio::spawn(async move {
            storage_clone.increment_counter(&key, 1, Duration::from_secs(60)).await
        });
        handles.push(handle);
    }
    
    // 等待所有操作完成
    for handle in handles {
        handle.await.unwrap().unwrap();
    }
    
    let duration = start.elapsed();
    println!("Memory storage: {} operations took {:?}", num_operations, duration);
    
    // 验证结果
    for i in 0..num_operations {
        let key = format!("{}_{}", key_prefix, i);
        let value = storage.get_counter(&key).await.unwrap();
        assert_eq!(value, 1);
    }
}

#[tokio::test]
async fn test_comprehensive_gateway_scenario() {
    // 模拟完整的网关场景：认证 + 限流 + 路由
    
    // 1. 设置认证
    let jwt_config = JwtConfig::default();
    let auth_provider = JwtAuthProvider::new(jwt_config).await.unwrap();
    
    // 2. 设置限流
    let storage = Arc::new(MemoryStorage::new());
    let algorithm = Box::new(TokenBucketAlgorithm::new(storage.clone()));
    let mut limiter = RateLimiter::new(algorithm, storage);
    
    let rate_config = RateLimitConfig {
        max_requests: 100,
        window_duration: Duration::from_secs(60),
        burst_capacity: Some(10),
        refill_rate: Some(10),
        enabled: true,
        ..Default::default()
    };
    
    let strategy = Box::new(UserBasedStrategy::new(rate_config));
    limiter = limiter.add_strategy(strategy);
    
    // 3. 模拟认证用户请求
    let claims = JwtClaims::new("user123".to_string(), Duration::from_hours(1));
    let token = auth_provider.generate_token(&claims).await.unwrap();
    
    let mut headers = HeaderMap::new();
    headers.insert("authorization", format!("Bearer {}", token).parse().unwrap());
    
    let auth_context = AuthContext::new(
        headers,
        "GET".to_string(),
        "/api/users/profile".to_string(),
        Some("192.168.1.100".to_string()),
    );
    
    // 4. 执行认证
    let principal = auth_provider.authenticate(&auth_context).await.unwrap();
    assert_eq!(principal.id, "user123");
    
    // 5. 执行限流检查
    let rate_context = RequestContext::new("/api/users/profile".to_string(), "GET".to_string())
        .with_user_id("user123".to_string())
        .with_client_ip("192.168.1.100".parse().unwrap());
    
    let rate_decision = limiter.is_allowed(&rate_context).await.unwrap();
    assert!(rate_decision.allowed);
    assert!(rate_decision.remaining > 0);
    
    println!("✅ 综合网关场景测试通过:");
    println!("   - 用户认证: 成功");
    println!("   - 限流检查: 通过 (剩余配额: {})", rate_decision.remaining);
    println!("   - 请求允许: 是");
}